using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using FU.Capstones.IMS.Web.Common;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.DataContracts;
using FU.Capstones.IMS.Web.Common.InventoryServiceProxy.EventArgs;
using FU.Capstones.IMS.Web.Silverlight.Models;
using Microsoft.Practices.Prism.Commands;
using Navigation.Silverlight;

namespace FU.Capstones.IMS.Web.Silverlight.ViewModels
{
    public class RoleDetailViewModel : ViewModelBase
    {
        public RoleDetailViewModel()
        {
            Model = new RoleDetailModel();
            ((RoleDetailModel)Model).GetSingleRoleCompleted += DoGetSingleRoleCompleted;
            ((RoleDetailModel)Model).InsertRoleCompleted += DoInsertRoleCompleted;
            ((RoleDetailModel)Model).UpdateRoleCompleted += DoUpdateRoleCompleted;
            ((RoleDetailModel)Model).GetAuthorizationCollectionCompleted += GetAuthorizationCollectionCompleted;

            ServiceCallCounter += ((RoleDetailModel)Model).GetAuthorizationCollectionAsync();

            IsFirstLoaded = false;
            ErrorMessageVisibility = Visibility.Collapsed;
            MessageVisibility = Visibility.Collapsed;

            CanEditOrAdd = CurrentUser.CanEditRole || CurrentUser.CanAddRole;
            CanAdd = CurrentUser.CanAddRole;
        }

        #region Do Completed Methods

        void GetAuthorizationCollectionCompleted(object sender, CollectionFeedbackCompletedEventArgs<Authorization> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    AuthorizationCollection = e.Result.Data;
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoUpdateRoleCompleted(object sender, FeedbackCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);

                if (e.Result.IsSuccessful)
                {
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoInsertRoleCompleted(object sender, SingleFeedbackCompletedEventArgs<int> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    isCreateNew = false;
                    Role.RoleID = e.Result.Data;
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        void DoGetSingleRoleCompleted(object sender, SingleFeedbackCompletedEventArgs<Role> e)
        {
            if (e.Error != null)
            {
                Message = e.Error.Message;
                SetMessageVisibility(false);
            }
            else
            {
                Message = e.Result.Message;
                SetMessageVisibility(e.Result.IsSuccessful);
                if (e.Result.IsSuccessful)
                {
                    Role = new Role()
                    {
                        BriefDescription = e.Result.Data.BriefDescription,
                        RoleID = e.Result.Data.RoleID,
                        RoleName = e.Result.Data.RoleName,
                        RoleCode = e.Result.Data.RoleCode,
                        FullDescription = e.Result.Data.FullDescription,
                        AuthorizationCollection = e.Result.Data.AuthorizationCollection
                    };
                    Backup();
                }
            }
            ServiceCallCounter -= WebConstants.MagicNumer;
        }

        #endregion

        #region Commands

        #region SaveCommand

        private DelegateCommand<object> saveCommand;
        public DelegateCommand<object> SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new DelegateCommand<object>(DoSaveCommand);
                return saveCommand;
            }
        }

        private void DoSaveCommand(object obj)
        {
            Role.ValidateAll();
            if (!Role.HasErrors)
            {
                if (isCreateNew)
                {
                    ServiceCallCounter += ((RoleDetailModel)Model).InsertRoleAsync(Role);
                }
                else
                {
                    ServiceCallCounter += ((RoleDetailModel)Model).UpdateRoleAsync(Role);
                }
            }
            else
            {
                Message = WebConstants.InvalidInputDataMessage;
                SetMessageVisibility(false);
            }
        }

        #endregion

        #region CancelCommand

        private DelegateCommand<object> cancelCommand;
        public DelegateCommand<object> CancelCommand
        {
            get
            {
                if (cancelCommand == null)
                    cancelCommand = new DelegateCommand<object>(DoCancelCommand);
                return cancelCommand;
            }
        }

        private void DoCancelCommand(object obj)
        {
            NavigationManager.NavigateTo(WebConstants.NavigationPages.RoleList);
        }

        #endregion

        #region ResetCommand

        private DelegateCommand<object> resetCommand;
        public DelegateCommand<object> ResetCommand
        {
            get
            {
                if (resetCommand == null)
                    resetCommand = new DelegateCommand<object>(DoResetCommand);
                return resetCommand;
            }
        }

        private void DoResetCommand(object obj)
        {
            if (isCreateNew)
                Role = new Role();
            else
            {
                Role = roleTemp;
                Backup();
            }
        }

        #endregion

        #region SelectCommand

        private DelegateCommand<int?> selectCommand;

        public DelegateCommand<int?> SelectCommand
        {
            get
            {
                if (selectCommand == null)
                    selectCommand = new DelegateCommand<int?>(DoSelectCommand);
                return selectCommand;
            }
        }

        private void DoSelectCommand(int? obj)
        {
            if (obj.HasValue && Role != null)
            {
                if (Role.AuthorizationCollection == null)
                    Role.AuthorizationCollection = new ObservableCollection<int>();
                Authorization temp = AuthorizationCollection.FirstOrDefault(x => x.AuthorizationID == obj.Value);
                if (temp != null)
                {
                    if (temp.IsSelected)
                    {
                        Role.AuthorizationCollection.Add(temp.AuthorizationID);
                    }
                    else
                    {
                        Role.AuthorizationCollection.Remove(temp.AuthorizationID);
                    }
                }
            }
        }

        #endregion

        #endregion

        #region Binding Properties

        private Role role;
        public Role Role
        {
            get { return role; }
            set
            {
                if (!ReferenceEquals(role, value))
                {
                    role = value;
                    RaisePropertyChanged(() => Role);
                }
            }
        }

        private ObservableCollection<Role> roleCollection;
        public ObservableCollection<Role> RoleCollection
        {
            get { return roleCollection; }
            set
            {
                if (!ReferenceEquals(roleCollection, value))
                {
                    roleCollection = value;
                    RaisePropertyChanged(() => RoleCollection);
                }
            }
        }

        private ObservableCollection<Authorization> authorizationCollection;
        public ObservableCollection<Authorization> AuthorizationCollection
        {
            get { return authorizationCollection; }
            set
            {
                if (!ReferenceEquals(authorizationCollection, value))
                {
                    authorizationCollection = value;
                    RaisePropertyChanged(() => AuthorizationCollection);
                }
            }
        }
        
        #endregion

        #region Fields

        private bool isCreateNew;
        private Role roleTemp;

        #endregion

        #region Implementation of INavigationAware

        public override void OnNavigate(object extraData)
        {
            int? roleID = (int?)extraData;
            isCreateNew = (roleID.HasValue == false || roleID.Value == 0);
            if (!isCreateNew)
            {
                IsFirstLoaded = true;
                ServiceCallCounter += ((RoleDetailModel)Model).GetSingleRoleAsync(roleID.Value);
            }
            else
            {
                Role = new Role();
            }
            Message = "Đang kết nối tới máy chủ...";
        }

        public override void OnLeave()
        {
            //throw new NotImplementedException();
        }

        #endregion

        protected override void HandleLoadingCompleted()
        {
            if (ServiceCallCounter == 0 && !isCreateNew && IsFirstLoaded)
            {
                MappWithCollection();
                IsFirstLoaded = false;
            }
        }

        private void Backup()
        {
            if (Role != null)
            {
                roleTemp = new Role()
                {
                    BriefDescription = role.BriefDescription,
                    RoleID = role.RoleID,
                    RoleName = role.RoleName,
                    RoleCode = role.RoleCode,
                    FullDescription = role.FullDescription
                };
            }
        }

        public void MappWithCollection()
        {
            if (Role.AuthorizationCollection != null && AuthorizationCollection != null)
            {
                int upper = Role.AuthorizationCollection.Count;
                for (int i = 0; i < upper; i++)
                {
                    Authorization au = AuthorizationCollection.FirstOrDefault(x => x.AuthorizationID == Role.AuthorizationCollection[i]);
                    if (au != null)
                        au.IsSelected = true;
                }

                AuthorizationCollection = new ObservableCollection<Authorization>(AuthorizationCollection.OrderByDescending(au => au.IsSelected));
            }
        }
    }
}